/*
 * Copyright (C) 2009,2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

#ifndef _ewindow_h
#define _ewindow_h

#include "etypes.h"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xft/Xft.h>

#include <sys/time.h>

#define eerror_event			0
#define ekey_press_event		1
#define ekey_release_event		2
#define ebutton_press_event		3
#define ebutton_release_event		4
#define epointer_motion_event		5
#define ebutton_motion_event		6
#define eenter_event			7
#define eleave_event			8
#define efocus_in_event			9
#define efocus_out_event		10
#define eresize_event			11
#define eexpose_event			12
#define emap_event			13
#define eunmap_event			14
#define etimer_event			15
#define eprotocol_event			16
#  define edelete_window_protocol	0

/*
 * Types
 */
struct ebitmap {
    Pixmap	 __bitmap;
    euint16_t	 width;
    euint16_t	 height;
    evector_t	*data;
    euint16_t	 __width;
    euint16_t	 __height;
    evector_t	*__data;
};

struct epixmap {
    Pixmap	 __pixmap;
    euint16_t	 width;
    euint16_t	 height;
    euint16_t	 __width;
    euint16_t	 __height;
};

struct ewindow {
    Window	 __window;
    euint16_t	 width;
    euint16_t	 height;
    eint16_t	 x;
    eint16_t	 y;
    euint32_t	 pixel;
    epixmap_t	*pixmap;
    euint8_t	 popup;
    euint8_t	 input;
    euint32_t	 events;
    ewindow_t	*parent;
    euint16_t	 __width;
    euint16_t	 __height;
    eint16_t	 __x;
    eint16_t	 __y;
#undef __pixel			/* darwin ppc */
    euint32_t	 __pixel;
    epixmap_t	*__pixmap;
    euint8_t	 __popup;
    euint8_t	 __input;
    euint32_t	 __events;
    ewindow_t	*__parent;
    ewindow_t	*__children;
    ewindow_t	*__prev;
    ewindow_t	*__next;
    XIC		*__xic;
};

struct eevent {
    ewindow_t	*window;	/* window object */
    euint32_t	 type;		/* event type */
    euint16_t	 width;		/* expose/resize width */
    euint16_t	 height;	/* expose/resize height */
    eint16_t	 x;		/* pointer x */
    eint16_t	 y;		/* pointer y */
    euint32_t	 state;		/* keyboard and pointer state */
    euint32_t	 detail;	/* keycode or button */
    XEvent	*__event;
};

typedef struct estate {
    GC		 gc;
    XftDraw	*draw;
    XftFont	*font;
    XftColor	 foreground;
    XftColor	 background;
} estate_t;

struct econtext {
    estate_t	*__state;
    ewindow_t	*drawable;	/* window or pixmap */
    evector_t	*font;		/* font specification */
    euint32_t	 background;	/* background pixel */
    euint32_t	 foreground;	/* foreground pixel */
    euint16_t	 line_width;
    ewindow_t	*__drawable;
    evector_t	*__font;
    euint32_t	 __background;
    euint32_t	 __foreground;
    euint16_t	 __line_width;
};

/* low/unreliable resolution timer for repeaters/timeouts in user
 * interfaces, reported as special events (not listening to events
 * means timers not being reported) */
struct etimer {
    etimer_t		*__next;	/* linked list */
    etimer_t		*__prev;
    ewindow_t		*window;	/* timer event target */
    euint32_t		 msec;		/* miliseconds timer resolution */
    euint8_t		 repeat;	/* single shot or repeater? */
    euint8_t		 pending;	/* status field */
    ewindow_t		*__window;
    euint32_t		 __msec;
    euint8_t		 __repeat;
    struct timeval	__tv;		/* when timer triggers */
};

struct epoint {
    eint16_t	 x;
    eint16_t	 y;
};

struct erect {
    euint16_t	 width;
    euint16_t	 height;
    eint16_t	 x;
    eint16_t	 y;
};

/*
 * Prototypes
 */
extern void
init_window(void);

extern ebool_t
edestroy_pixmap(epixmap_t *pixmap);

extern ebool_t
edestroy_window(ewindow_t *window);

extern ebool_t
edestroy_context(econtext_t *context);

#endif /* _ewindow_h */
